`define VERSION 32'h20000024

module debugger_ch341a_ft232h (
    input           clk,
    input           clk_50M,
    input           reset_n,

    output reg      ch341a_miso,//d7 data out
    output reg      ch341a_ack, //d6 debug模块请求置1，cs0拉低置0
    input           ch341a_mosi,//d5
	//                           //d4
    input           ch341a_sck, //d3
    input           ch341a_cs2, //d2 data out
    input           ch341a_cs1, //d1 data in
    input           ch341a_cs0, //d0 cmd in /data out

    output [31:0] debug_address_out,
	 output [31:0] debug_writedata_out,

    input dummy
);

assign debug_address_out = debug_address;
assign debug_writedata_out = debug_writedata;

  reg command_req;
  reg command_ack;
  reg debug_data_send;
  reg [31:0] debug_data_out;
  wire [31:0] data;
  wire [7:0] command;
  assign debug_regAddr = debug_address[5:0];






localparam FIFO_SIZE = 2;

reg [FIFO_SIZE:0] fpga_addr;
wire [31:0] fpga_read_data;
reg         fpga_write;
reg  [31:0] fpga_write_data;

assign ft_AC4_NSIWU = 1;

localparam MEM_READ             = 0;
localparam MEM_WRITE            = 1;
localparam INS_READ             = 2;
localparam REG_READ             = 3;
localparam MEM_READ_TRANS       = 4;
localparam MEM_WRITE_TRANS      = 5;
localparam INS_READ_TRANS       = 6;
localparam VGA_TRANS            = 7;




  //00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
  reg [39:0] ch341a_cmd_data;
  assign command = ch341a_cmd_data[7:0];
  assign data = ch341a_cmd_data[39:8];
  //输出，32bit，ack 上升时锁存
  reg [31:0] ch341a_data_out_buff;//out data
  always @(posedge ch341a_sck or posedge ch341a_ack) begin
    if (ch341a_ack) begin//ack拉高时锁存
      ch341a_miso <= 0;
      ch341a_data_out_buff <= debug_data_out;
    end else begin
      if(!ch341a_cs0) begin
        ch341a_miso <= ch341a_data_out_buff[0];
        ch341a_data_out_buff[30:0] <= ch341a_data_out_buff[31:1];
      end
    end
  end

  always @(posedge clk_50M or negedge reset_n) begin
    if(!reset_n) begin
      ch341a_ack <= 1'b0;
    end else begin
      if(debug_data_send)begin
        ch341a_ack <= 1'b1;
      end 
      if (!ch341a_cs0)begin
        ch341a_ack <= 1'b0;
      end
    end
  end
  
  //5个字节指令加数据
  always @(posedge ch341a_sck) begin
    if(!ch341a_cs0)begin
      ch341a_cmd_data <= {ch341a_mosi, ch341a_cmd_data[39:1]};
    end
  end

  reg ch341a_cs0_buff;//新
  reg ch341a_cs0_buff2;//旧
  always @(posedge clk_50M or negedge reset_n) begin
    if (!reset_n) begin
      ch341a_cs0_buff <= 1;
      ch341a_cs0_buff2 <= 1;
      command_req <= 0;
    end else begin
      ch341a_cs0_buff <= ch341a_cs0;
      ch341a_cs0_buff2 <= ch341a_cs0_buff;
      
      if(!ch341a_cs0_buff2 && ch341a_cs0_buff)begin //上升沿触发debug指令
        command_req <= 1;
      end
      
      if(command_ack)begin
        command_req <= 0;
      end
    end
  end
//000000000000000000000000000000000000000000000000000000000000000000000000000


always @(*)begin
  case(command[5:0])

    8'h20: begin debug_data_out<=data; end //GET_CONST_ECHO
    8'h24: begin debug_data_out<=`VERSION; end //GET_CONST_ECHO

    default: begin
      debug_data_out<=0;
    end
  endcase
end
  
  reg vga_control_by_debugger_reg2;
  reg       transfer_req;
  reg [31:0] debug_address;
  reg [31:0] debug_writedata;
  reg [31:0] debug_length;
  reg [0:0] debug_mem_step;
  reg [9:0] vga_count;
  reg spirom_debug_read_ack_buff;
  reg spirom_debug_write_ack_buff;
  reg mem_ack_buff;
  reg reset_fifo;
  always @(posedge clk_50M or negedge reset_n) begin
    if (!reset_n) begin
      reset_fifo <= 0;
      transfer_req <= 0;
      
      debug_mem_step <= 0;
      

      debug_address<=0;
      debug_writedata<=0;
      


      command_ack <= 0;
      debug_data_send<=0;
      mem_ack_buff <= 0;



      vga_control_by_debugger_reg2 <= 0;

      //vga_control_by_debugger <= 0;
    end else begin

      debug_data_send <= 0;

      if(command_req && !command_ack)begin
        case(command[5:0])
        
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        8'h16 : begin debug_data_send<=1; debug_address <= data; command_ack<=1; end//SET_DEBUG_ADDRESS
        8'h17 : begin debug_data_send<=1; debug_writedata <= data; command_ack<=1; end//SET_DEBUG_WRITEDATA


        8'h20,8'h21,8'h22,8'h23,8'h24,8'h25,8'h26,8'h27,
        8'h28,8'h29,8'h2A,8'h2B,8'h2C,8'h2D,8'h2E,8'h2F : begin
          debug_data_send<=1; command_ack<=1;
        end //GET_CONST_ECHO

		  
        default: begin
          command_ack<=1;
        end

        
        endcase

      end

      if(!command_req && command_ack)begin
        command_ack<=0;
      end
      
      if(reset_fifo)begin
        debug_mem_step <= 0;
      end
    end
  end



endmodule
